Модуль:Инфобокс персонажа
local infoboxCharacter = {} function infoboxCharacter.infoboxCreate(frame) --подготовка local args = frame.args --создание контейнера local infobox = mw.html.create("div") infobox:addClass("infoboxCharacter") infobox:attr("id", "infoboxCharacter-"..args.number) infobox:css("width", args.width) --функции --разбиение строки на массив подстрок по определенному символу function split(str, separator, reg) local result = {} --Проверка на образец if (not reg) then regExp = true else regExp = false end --переменные позиций local n local k --управляющие переменные local s = 0 local i = 1 --главный цикл while k ~= str:len() do --поиск сепаратора local substring n, k = string.find(str, separator, s + 1, regExp) --если поиск не дал результатов if (k nil or n nil) then resulti = string.sub(str, s + 1, str:len()) break end substring = string.sub(str, s + 1, n - 1) --добавление результата if substring ~= "" then resulti = substring i = i + 1 end s = k end return result end --программа --десериализация аргументов local argsImg = infoboxCharacter.tools.argsDeSerial(args.images, {"@",";",":"}, "^@;:∅") local argsKind = infoboxCharacter.tools.argsParse(args.kind, argsImg, {"@",";"}, "^@;") local argsAge = infoboxCharacter.tools.argsParse(args.age, argsImg, {"@",";"}, "^@;") local argsOccupation = infoboxCharacter.tools.argsParse(args.occupation, argsImg, {"@",";"}, "^@;") local argsResidence = infoboxCharacter.tools.argsParse(args.residence, argsImg, {"@",";"}, "^@;") local argsVoice = infoboxCharacter.tools.argsDeSerial(args.voice, {";",":"}, "^;:") local argsRelatives = infoboxCharacter.tools.argsDeSerial(args.relatives, {";",":"}, "^;:") local argsColors = infoboxCharacter.tools.argsDeSerial(args.colors, {"@","!",":",";","/"}, "^@!:;/") --подготовка элементов --Обёртка local infoboxContainer = mw.html.create("div") --заголовок local header = infoboxCharacter.build.headerCreate(args.headerColor, args.headerFontColor, args.headerFontSize, args.name) --титул local title if (args.title ~= "") then title = infoboxCharacter.build.titleCreate(args.title, argsImg) end --изображения local images if (argsImg1 and argsImg11) then images = infoboxCharacter.build.imagesCreate(argsImg, args, argsKind, argsAge, argsOccupation) end --вид local kind if (argsKind) then kind = infoboxCharacter.build.kindCreate(argsKind, args.gender, args.number) end --пол local gender if (args.gender ~= "") then gender = infoboxCharacter.build.genderCreate(args.gender, argsKind, argsAge, args.number) end --информация local informationTable if (argsOccupation or argsResidence or args.owner ~= "" or args.habitat ~= "") then informationTable = infoboxCharacter.build.informationTableCreate(argsOccupation, argsResidence, args.owner, args.habitat, args.tableIndent) end --озвучка local voice if(argsVoice12 or argsVoice22 or argsVoice32 or argsVoice42 or argsVoice5) then voice = infoboxCharacter.build.informationCollapsibleTableCreate(argsVoice, args.headerColor, args.headerFontColor, args.tableIndent, "Озвучка") end --родственники local relatives if (argsRelatives1) then relatives = infoboxCharacter.build.informationCollapsibleTableCreate(argsRelatives, args.headerColor, args.headerFontColor, args.tableIndent, "Родственники") end --цвета local colors local cutieMark if (argsColors112 or argsColors212 or argsColors312 or (argsColors4 and argsColors412)) then colors = infoboxCharacter.build.colorsCreate(argsColors, args.headerColor, args.headerFontColor, "Внешний вид") end --внешние кнопки local outerButtons if (#argsImg > 1) then outerButtons = infoboxCharacter.build.outerButtonsCreate(argsImg, args) end local innerButtons --внутренние кнопки if (argsImg) then innerButtons = infoboxCharacter.build.innerButtonsCreate(argsImg, args, argsKind, argsAge) end --построение инфобокса --заголовок infobox:node(header) --титул if (title) then infobox:node(title) end --изображения if (images) then for i = 1, #images do infobox:node(imagesi) end end --внутренние кнопки if (innerButtons) then for i = 1, #innerButtons do infobox:node(innerButtonsi) end end --вид if (kind) then infobox:node(kind) end --пол if (gender) then infobox:node(gender) end --информация if (informationTable) then infobox:node(informationTable) end --озвучка if (voice) then infobox:node(voice) end --родственники if (relatives) then infobox:node(relatives) end --цвета if (colors) then infobox:node(colors) end --инфобокс infoboxContainer:node(infobox) --наружные кнопки if (outerButtons) then infoboxContainer:node(outerButtons) end return infoboxContainer end --создание элементов infoboxCharacter.build = {} --заголовок function infoboxCharacter.build.headerCreate(backgroundColor, fontColor, fontSize, name) local header = mw.html.create("div") header:addClass("infoboxCharacterHeader") header:css("background-color", backgroundColor) local headerText = mw.html.create("div") headerText:cssText("margin:auto; color:"..fontColor.."; font-size:"..fontSize) headerText:wikitext(name) header:node(headerText) return header end --титул function infoboxCharacter.build.titleCreate(titleText, images) local title = mw.html.create("div") if (not images) then title:css("margin-bottom", "6px") end title:addClass("infoboxCharacterTitle") title:wikitext(titleText) return title end --изображения function infoboxCharacter.build.imagesCreate(argsImg, args, argsKind, argsAge, argsOccupation) local images = {} if (#argsImg 1 and #argsImg1 1) then--если картинка одна local image = mw.html.create("div") image:wikitext("[[Файл:"..argsImg112.."|"..args.width.."|link=]]") images1 = image else for i = 1, #argsImg do local imgBlock = mw.html.create("div") imgBlock:attr("id", "imgBlock-"..args.number.."-"..i) if (i > 1) then--если блок не первый в списке imgBlock:css("display", "none") end for j = 1, #argsImgi do local image = mw.html.create("div") image:attr("id", "image-"..args.number.."-"..i.."-"..j) if (argsImgij3 and j 1) then--проверка правильности заполнения image:wikitext("[[Файл:"..argsImgij3.."|"..args.width.."|link=]]") elseif (argsImgij2 and j ~= 1) then image:wikitext("[[Файл:"..argsImgij2.."|"..args.width.."|link=]]") else image:wikitext("Ошибка. Проверь изображения.") end if (j > 1) then--если изображение не первое в списке image:css("display", "none") end --информация для скрипта if (argsKind) then--вид image:attr("data-kind", argsKindij) end if (argsAge) then--пол local gender = infoboxCharacter.build.auxiliary.groupCheck(args.gender, argsKindij, argsAgeij) image:attr("data-gender", gender) end if (argsOccupation) then--занятие image:attr("data-occupation", argsOccupationij) end imgBlock:node(image) end imagesi = imgBlock end end return images end --вид function infoboxCharacter.build.kindCreate(argsKind, gender, argNum) local kind = mw.html.create("div") kind:attr("id", "InfoboxCharacterKind-"..argNum) kind:addClass("infoboxCharacterKindGender colorLink") if (argsKind11 "{0}") then kind:css("display", "none") return kind end local textKind local kindImg if (mw.ustring.lower(argsKind11) "единорог") then textKind = "Единорог" kindImg = "Unicorn picto" elseif (mw.ustring.lower(argsKind11) "пегас") then textKind = "Пегас" kindImg = "Pegasus picto" elseif (mw.ustring.lower(argsKind11) "земнопони" or argsKind11 "земной пони" or argsKind11 "земная пони") then if (mw.ustring.lower(gender) "жен" or mw.ustring.lower(gender) "женский") then textKind = "Земная пони" else textKind = "Земной пони" end kindImg = "Earthpony picto" elseif (mw.ustring.lower(argsKind11) "аликорн") then textKind = "Аликорн" kindImg = "Alicorn picto" end if (textKind) then local imgBlock = mw.html.create("div") imgBlock:cssText("position:absolute; left:0; top:0") imgBlock:wikitext("link=") kind:css("padding-left", "23px") kind:node(imgBlock) kind:wikitext(""..textKind.."") else kind:css("padding-left", "3px") kind:wikitext(""..argsKind11.."") end return kind end --пол function infoboxCharacter.build.genderCreate(argGender, argsKind, argsAge, argNum) local checkGender = mw.ustring.lower(argGender) if (not (checkGender "муж" or checkGender "мужской" or checkGender "жен" or checkGender "женский")) then return nil end local gender = mw.html.create("div") gender:addClass("infoboxCharacterKindGender") local textGender = infoboxCharacter.build.auxiliary.groupCheck(argGender, argsKind11, argsAge11) local genderImg if (checkGender "муж" or checkGender "мужской") then genderImg = "Male picto" else genderImg = "Female picto" end local imgBlock = mw.html.create("div") imgBlock:cssText("position:absolute; left:0; top:0") imgBlock:wikitext("link=") gender:attr("id", "InfoboxCharacterGender-"..argNum) gender:css("padding-left", "23px") gender:node(imgBlock) gender:wikitext(""..textGender.."") return gender end --информация function infoboxCharacter.build.informationTableCreate(argsOccupation, argsResidence, owner, habitat, tableIndent) local informationTable = mw.html.create("table") local counter = 0 informationTable:cssText("text-align:left; border-collapse:collapse") if (argsOccupation) then local line = infoboxCharacter.build.auxiliary.lineCreate("Занятие", argsOccupation11, tableIndent) counter = counter + 1 if (argsOccupation11 "{0}") then line:css("display", "none") counter = counter - 1 end informationTable:node(line) end if (argsResidence) then local line = infoboxCharacter.build.auxiliary.lineCreate("Проживает", argsResidence11, tableIndent) counter = counter + 1 if (argsResidence11 "{0}") then line:css("display", "none") counter = counter - 1 end informationTable:node(line) end if (owner ~= "") then local line = infoboxCharacter.build.auxiliary.lineCreate("Владелец", owner, tableIndent) informationTable:node(line) counter = 1 end if (habitat ~= "") then local line = infoboxCharacter.build.auxiliary.lineCreate("Ареал обитания", habitat, tableIndent) informationTable:node(line) counter = 1 end if (counter 0) then informationTable:css("display", "none") end return informationTable end --озвучка и родственники function infoboxCharacter.build.informationCollapsibleTableCreate(args, headerColor, headerFontColor, tableIndent, label) local informationTable = infoboxCharacter.build.auxiliary.collapsibleTableCreate(label, headerColor, headerFontColor) informationTable:css("text-align", "left") for i = 1, #args do if (argsi1 and argsi2) then local line = infoboxCharacter.build.auxiliary.lineCreate(argsi1, argsi2, tableIndent) informationTable:node(line) end end return informationTable end --цвета function infoboxCharacter.build.colorsCreate(argsColors, headerColor, headerFontColor, label) local colorTable = infoboxCharacter.build.auxiliary.collapsibleTableCreate(label, headerColor, headerFontColor) local colorCells = {} for i = 1, #argsColors do if (argsColorsi and argsColorsi11 and argsColorsi12) then local colorCell = mw.html.create("td") local colorbox = infoboxCharacter.build.auxiliary.colorBox(argsColorsi121, argsColorsi13) colorCell:wikitext(""..argsColorsi1111.." ") colorCell:node(colorbox) colorCells+ 1 = colorCell end end if (#colorCells > 0) then local length = #colorCells local colspan local tr for i = 1, length do if (length - i 1 and length % 3 2) then colspan = "3" else if (length i and length % 3 1) then colspan = "6" else colspan = "2" end end if i % 3 1 then tr = mw.html.create("tr") tr:css("text-align", "center") end colorCellsi:attr("colspan", colspan) tr:node(colorCellsi) if (i % 3 0 or length - i 0) then colorTable:node(tr) end end end return colorTable end --кнопки внешние function infoboxCharacter.build.outerButtonsCreate(argsImg, args) local buttonsSection = mw.html.create("div") buttonsSection:addClass("infoboxCharacterOuterButtonsSection") for i = 1, #argsImg do local button = mw.html.create("div") button:addClass("infoboxCharacterOuterButton") button:wikitext(argsImgi11) button:attr("id", "outerButton-"..args.number.."-"..i) buttonsSection:node(button) end return buttonsSection end --кнопки внутренние function infoboxCharacter.build.innerButtonsCreate(argsImg, args) local buttonsSections = {} for i = 1, #argsImg do if(#argsImgi > 1) then local buttonsSection = mw.html.create("div") buttonsSection:addClass("infoboxCharacterInnerButtonsSection") buttonsSection:attr("id", "innerButtonsSection-"..args.number.."-"..i) if (i > 1) then buttonsSection:css("display", "none") end for j = 1, #argsImgi do local button = mw.html.create("div") button:addClass("infoboxCharacterInnerButton") button:attr("id", "innerButton-"..args.number.."-"..i.."-"..j) --подписи кнопок if (argsImgij3) then button:attr("data-description", argsImgij2) else button:attr("data-description", argsImgij1) end buttonsSection:node(button) end buttonsSections+ 1 = buttonsSection end end if (buttonsSections1) then return buttonsSections else return nil end end --вспомогательные функции infoboxCharacter.build.auxiliary = {} --создание пустой сворачивающейся таблицы с заголовком function infoboxCharacter.build.auxiliary.collapsibleTableCreate(label, color, fontColor) table = mw.html.create("table") table:cssText("width:100%; margin:3px 0; border-collapse:collapse") table:addClass("mw-collapsible mw-collapsed") headerLine = mw.html.create("tr") header = mw.html.create("th") header:cssText("text-align:left; padding-left:3em") header:cssText("background-color:"..color.."; color:"..fontColor) header:wikitext(label) header:attr("colspan", "6") headerLine:node(header) table:node(headerLine) return table end --создание строки таблицы function infoboxCharacter.build.auxiliary.lineCreate(title, text, tableIndent) local indent = tableIndent if (indent "") then indent = "30%" end local line = mw.html.create("tr") local leftColumn = mw.html.create("th") leftColumn:cssText("width:"..indent.."; vertical-align:top;") leftColumn:wikitext(title) line:node(leftColumn) local rightColumn = mw.html.create("td") rightColumn:wikitext(text) line:node(rightColumn) return line end --Создание колорбокса function infoboxCharacter.build.auxiliary.colorBox(colors, borderColor) local colorBox = mw.html.create("div") colorBox:addClass("colorBox") if (borderColor) then colorBox:css("border", "2px solid "..borderColor11) else colorBox:css("border", "1px solid gray") end width = 100 / #colors for i = 1, #colors do local innerElement = mw.html.create("div") innerElement:cssText("height:100%; display:inline-block; background-color:"..colorsi.."; width:"..width.."%") innerElement:attr("title", colorsi) colorBox:node(innerElement) end return colorBox end --Определение половидовозрастной группы function infoboxCharacter.build.auxiliary.groupCheck(gender, argsKind, argsAge) local checkGender = mw.ustring.lower(gender) local group if (checkGender "муж" or checkGender "мужской") then local checkKind = mw.ustring.lower(argsKind) if (checkKind "человек") then if (argsAge) then local age = mw.ustring.lower(argsAge) if (age "взр" or age "взрослый") then group = "Мужчина" elseif (age "дет" or age "детский") then group = "Мальчик" else group = "Юноша" end else group = "Юноша" end elseif (checkKind "единорог" or checkKind "пегас" or checkKind "земнопони" or checkKind "земной пони" or checkKind "аликорн") then if (argsAge) then local age = mw.ustring.lower(argsAge) if (age "дет" or age "детский") then group = "Жеребёнок" else group = "Жеребец" end else group = "Жеребец" end else group = "Муж." end elseif (checkGender "жен" or checkGender "женский") then local checkKind = mw.ustring.lower(argsKind) if (checkKind "человек") then if (argsAge) then local age = mw.ustring.lower(argsAge) if (age "взр" or age "взрослый") then group = "Женщина" elseif (age "дет" or age "детский") then group = "Девочка" else group = "Девушка" end else group = "Девушка" end elseif (checkKind "единорог" or checkKind "пегас" or checkKind "земнопони" or checkKind "земная пони" or checkKind "аликорн") then if (argsAge) then local age = mw.ustring.lower(argsAge) if (age "дет" or age "детский") then group = "Кобылка" else group = "Кобыла" end else group = "Кобыла" end else group = "Жен." end end return group end --служебные функции infoboxCharacter.tools = {} function infoboxCharacter.tools.split(str, separator, reg) local result = {} if separator "" then result1 = str return result end local n local k local s = 0 if (not reg) then regExp = true else regExp = false end local i = 1 while k ~= str:len() do local substring n, k = string.find(str, separator, s + 1, regExp) if (k nil or n nil) then resulti = string.sub(str, s + 1, str:len()) break end substring = string.sub(str, s + 1, n - 1) if substring ~= "" then resulti = substring end s = k i = i + 1 end return result end function infoboxCharacter.tools.argsDeSerial(args, separators, pattern, iterNum) if (not iterNum) then iterNum = 1 end if (not pattern) then pattern = "" end local splitArray = infoboxCharacter.tools.split(args, separatorsiterNum) if (iterNum #separators) then return splitArray else local splitArray2 = {} for i = 1, #splitArray do if (splitArrayi ~= nil and string.find(splitArrayi, pattern) ~= nil) then splitArray2i = infoboxCharacter.tools.argsDeSerial(splitArrayi, separators, pattern, iterNum + 1) end end return splitArray2 end end function infoboxCharacter.tools.argsParse(args, images, separators, pattern) local result = {} local argsDeSerial = infoboxCharacter.tools.argsDeSerial(args, separators, pattern) if (not images1) then if (not argsDeSerial1) then return nil end result1 = {argsDeSerial11} return result else if (#argsDeSerial 0) then return nil else local template = "{0}" for i = 1, #images do resulti = {} if (not argsDeSeriali) then argsDeSeriali = {} end for j = 1, #imagesi do if (argsDeSerialij nil) then resultij = template else if (string.match(argsDeSerialij, "!?{%d+%.%d+}")) then local a, b = string.match(argsDeSerialij, "!?{(%d+)%.(%d+)}") a = tonumber(a) b = tonumber(b) if (a > i or b >= j) then resultij = "проверь ссылку" else resultij = resultab if (string.sub(argsDeSerialij, 1, 1) "!") then template = resultab end end else if (string.sub(argsDeSerialij, 1, 1) "!") then template = string.sub(argsDeSerialij, 2, string.len(argsDeSerialij)) resultij = template else resultij = argsDeSerialij end end end end end end end return result end return infoboxCharacter